package top.frsf.rpc.code.encode;

import cn.hutool.json.JSONUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import top.frsf.rpc.protocol.RpcMessage;
import top.frsf.rpc.protocol.head.RpcHeader;

import java.nio.charset.StandardCharsets;

/**
 * PRC 消息编码器
 *
 * @author He Kuntao
 * @since 2025/7/2 11:31
 */
public class RpcMessageEncoder extends MessageToByteEncoder<RpcMessage<?>> {

    @Override
    protected void encode(ChannelHandlerContext ctx, RpcMessage<?> msg, ByteBuf out) throws Exception {
        // 1.序列化body并转字节数组
        RpcHeader header = msg.getHeader();
        Object body = msg.getBody();
        byte[] bodyBytes = JSONUtil.toJsonStr(body).getBytes(StandardCharsets.UTF_8);
        header.setBodyLength(bodyBytes.length);

        // 2.写入协议头
        writeHeader(out, header);

        // 3.写入消息体
        out.writeBytes(bodyBytes);
    }

    /**
     * 写入协议头
     *
     * @param out 字节缓冲区
     * @param header RPC 协议头
     */
    private void writeHeader(ByteBuf out, RpcHeader header) {
        out.writeShort(header.getMagic());
        out.writeByte(header.getVersion());
        out.writeByte(header.getFlags());
        out.writeByte(header.getSerialType());
        out.writeByte(header.getStatus());
        out.writeLong(header.getRequestId());
        out.writeInt(header.getBodyLength());
    }
}

